package com.example.hibernate.model.dal;

import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

import com.example.hibernate.model.entity.GenericEntity;
import com.example.hibernate.model.util.HibernateUtil;

public abstract class AbstractDAL<E extends GenericEntity> implements GenericDAL<E> {

	private final Class<?> clazz;

	public AbstractDAL(Class<?> clazz) {
		this.clazz = clazz;
	}

	@Override
	public boolean insertEntity(E entity) {
		boolean result = false;
		SessionFactory sessionFactory = null;
		Session session = null;
		try {
			sessionFactory = HibernateUtil.getSessionFactory();
			session = sessionFactory.openSession();
			session.beginTransaction();
			session.save(entity);
			session.getTransaction().commit();
			result = true;
		} catch (Exception e) {
			if (session != null) session.getTransaction().rollback();
			e.printStackTrace();
		} finally {
			if (session != null) session.close();
		}
		return result;
	}

	@Override
	public boolean updateEntity(E entity) {
		boolean result = false;
		SessionFactory sessionFactory = null;
		Session session = null;
		try {
			sessionFactory = HibernateUtil.getSessionFactory();
			session = sessionFactory.openSession();
			session.beginTransaction();
			session.update(entity);
			session.getTransaction().commit();
			result = true;
		} catch (Exception e) {
			if (session != null) session.getTransaction().rollback();
			e.printStackTrace();
		} finally {
			if (session != null) session.close();
		}
		return result;
	}

	@Override
	public boolean deleteEntity(E entity) {
		boolean result = false;
		SessionFactory sessionFactory = null;
		Session session = null;
		try {
			sessionFactory = HibernateUtil.getSessionFactory();
			session = sessionFactory.openSession();
			session.beginTransaction();
			session.delete(entity);
			session.getTransaction().commit();
			result = true;
		} catch (Exception e) {
			if (session != null) session.getTransaction().rollback();
			e.printStackTrace();
		} finally {
			if (session != null) session.close();
		}
		return result;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<E> getAllEntity() {
		List<E> entities = null;
		SessionFactory sessionFactory = null;
		Session session = null;
		try {
			sessionFactory = HibernateUtil.getSessionFactory();
			session = sessionFactory.openSession();
			session.beginTransaction();
			Query query = session.createQuery("FROM " + clazz.getName());
			entities = query.list();
			session.getTransaction().commit();
		} catch (Exception e) {
			if (session != null) session.getTransaction().rollback();
			e.printStackTrace();
		} finally {
			if (session != null) session.close();
		}
		return entities;
	}

	@SuppressWarnings("unchecked")
	@Override
	public E findEntityById(long id) {
		E entity = null;
		SessionFactory sessionFactory = null;
		Session session = null;
		try {
			sessionFactory = HibernateUtil.getSessionFactory();
			session = sessionFactory.openSession();
			session.beginTransaction();
			entity = (E) session.get(clazz, id);
			session.getTransaction().commit();
		} catch (Exception e) {
			if (session != null) session.getTransaction().rollback();
			e.printStackTrace();
		} finally {
			if (session != null) session.close();
		}
		return entity;
	}
}
